package com.bcx.crm.spring.websocket.webSocket2;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.ArrayList;

/**
 * @Author: ys
 * @Date:Create in 2018/5/15 16:37
 * @Description: 该对象提供了客户端连接，关闭，错误，发送等方法，重写这几个方法即可实现自定义业务逻辑
 */
public class SpringWebSocketHandler extends TextWebSocketHandler {
    //已建立连接的用户
    private static final ArrayList<WebSocketSession> users;//这个会出现性能问题，最好用Map来存储，key用userid
    private static Logger logger = LoggerFactory.getLogger(SpringWebSocketHandler.class);
    static {
        users = new ArrayList<>();
    }

    public SpringWebSocketHandler() {
        // TODO Auto-generated constructor stub
    }

    /**
     * 连接成功时候，会触发页面上onopen方法
     */
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // TODO Auto-generated method stub
        System.out.println("connect to the websocket success......当前数量:"+users.size());
        users.add(session);
        //这块会实现自己业务，比如，当用户登录后，会把离线消息推送给用户
        //TextMessage returnMessage = new TextMessage("你将收到的离线");
        //session.sendMessage(returnMessage);
    }

    /**
     * 关闭连接时触发
     */
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.debug("websocket connection closed......");
        String username= (String) session.getAttributes().get("WEBSOCKET_USERNAME");
        System.out.println("用户"+username+"已退出！");
        users.remove(session);
        System.out.println("剩余在线用户"+users.size());
    }

    /**
     * 处理前端你发送的文本消息
     * js调用websocket.send时候，会调用该方法
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String userName =(String) session.getAttributes().get("WEBSOCKET_USERNAME");
        //获取提交过来的消息详情
        logger.debug("收到用户："+userName+"发送的消息，内容为："+message.toString());
        //回复一条消息        //发送给自己   reply msg：
        session.sendMessage(new TextMessage(userName+" : "+message.getPayload()));  //给当前WebSockectSession发送消息，与sendMessageToUsers()方法不排除自己一样
//        super.handleTextMessage(session, message);
        sendMessageToUsers(userName,message);  //将消息发送给除自己以外的所有人
    }

    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if(session.isOpen()){
            session.close();
        }
        logger.debug("websocket connection closed......");
        users.remove(session);
    }

    public boolean supportsPartialMessages() {
        return false;
    }


    /**
     * 给某个用户发送消息
     *
     * @param userName ： 登录的用户名
     * @param message ：将要发送给该用户的消息
     */
    public void sendMessageToUser(String userName, TextMessage message) {
        for (WebSocketSession user : users) {
            if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) {
                try {
                    if (user.isOpen()) {
                        user.sendMessage(message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }

    /**
     * 给所有在线用户发送消息
     *
     * @param message ：要发送的消息
     */
    public void sendMessageToUsers(String userName,TextMessage message) {
        for (WebSocketSession user : users) {
            String webSocketUserName = (String) user.getAttributes().get("WEBSOCKET_USERNAME");
            if (!webSocketUserName.equals(userName)){
                try {
                    if (user.isOpen()) {
                        user.sendMessage(new TextMessage(userName+" : "+message.getPayload()));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
